package org.boulderfoodrescue.webapp.client.options;

import java.util.List;

import org.boulderfoodrescue.webapp.client.Presenter;
import org.boulderfoodrescue.webapp.client.events.UserInfoUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.UserInfoUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.UsersListUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.UsersListUpdatedHandler;
import org.boulderfoodrescue.webapp.client.managers.LoginInfoManager;
import org.boulderfoodrescue.webapp.client.managers.UserAccountManager;
import org.boulderfoodrescue.webapp.client.options.manageusers.ManageUsersPanel;
import org.boulderfoodrescue.webapp.client.options.manageusers.UsersCellTable;
import org.boulderfoodrescue.webapp.client.options.myinfo.MyInfoPanel;
import org.boulderfoodrescue.webapp.client.options.volunteerinfo.VolunteerInfoPanel;
import org.boulderfoodrescue.webapp.shared.LoginInfo;
import org.boulderfoodrescue.webapp.shared.UserAccount;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails.AccessLevel;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.ui.Widget;

public class OptionsPresenter implements Presenter, OptionsInterface{
	private EventBus eventBus;
	private OptionsView optionsView;
	private OptionsPanel optionsPanel;
	private OptionsSidebar optionsSidebar;
	private MyInfoPanel myInfoPanel;
	private VolunteerInfoPanel volunteerInfoPanel;
	private ManageUsersPanel manageUsersPanel;
	private UsersCellTable usersCellTable;
	private UserAccountDetails newUser;
	
	public OptionsPresenter(EventBus eventBus)
	{
		this.eventBus = eventBus;
		bind();
		LoginInfo loginInfo = LoginInfoManager.getLoginInfo();
		if(loginInfo.getAccessLevel().compareTo(AccessLevel.Admin) >= 0){
			List<UserAccountDetails> list = UserAccountManager.getAccountUsers();
			usersCellTable = new UsersCellTable(eventBus, list);
			manageUsersPanel = new ManageUsersPanel(usersCellTable, this);
		}
		UserAccount user =  UserAccountManager.getUserAccount();
		
    if(loginInfo.getAccessLevel().compareTo(AccessLevel.Volunteer) >= 0){
      volunteerInfoPanel = new VolunteerInfoPanel(user);
    }
		
		myInfoPanel = new MyInfoPanel(user, this);
		
		optionsSidebar = new OptionsSidebar(loginInfo.getAccessLevel());
		
		optionsPanel = new OptionsPanel(myInfoPanel, volunteerInfoPanel, manageUsersPanel);
		
		optionsView = new OptionsView(optionsSidebar, optionsPanel);
	}

	private void bind()
	{
		eventBus.addHandler(UsersListUpdatedEvent.getType(), 
				new UsersListUpdatedHandler(){
			@Override
			public void onUserAdded(UsersListUpdatedEvent event) {
				if(usersCellTable != null)
					usersCellTable.addUser(event.getValue());
				if(event.getValue() == newUser){
				  newUser = null;
				  manageUsersPanel.onAddUserCompleted();
				}
			}
			@Override
			public void onUserUpdated(UsersListUpdatedEvent event) {
				if(usersCellTable != null)
					usersCellTable.refresh();
			}
			@Override
			public void onUserRemoved(UsersListUpdatedEvent event) {
				if(usersCellTable != null)
					usersCellTable.removeUser(event.getValue());
			}
      @Override
      public void onUserAddFailed(UsersListUpdatedEvent event) {
        if(event.getValue() == newUser){
          newUser = null;
          manageUsersPanel.onAddUserCompleted();
        }
      }
		});
		eventBus.addHandler(UserInfoUpdatedEvent.getType(), 
				new UserInfoUpdatedHandler(){
					@Override
          public void onUserUpdated(UserInfoUpdatedEvent event) {
	          if(myInfoPanel != null)
	          	myInfoPanel.setUserAccountData(event.getValue());
	            myInfoPanel.onUpdateMyInfoComplete();
	            volunteerInfoPanel.setUserAccountData(event.getValue());
	            volunteerInfoPanel.onUserAccountUpdateComplete();
          }
		});
	}

	@Override
	public Widget getWidget() {
		return optionsView;
	}

  @Override
  public void onAddingNewUser(UserAccountDetails user) {
    newUser = user;
  }

}
